package tr.edu.boun.phys.springmassmodel;

import java.util.Vector;

public class SpringMassModel {
	
	private Vector<Spring> springs;
	private Vector<Mass> masses;
	private Vector<Vector2D> forces;
	
	public SpringMassModel() {
		masses = new Vector<Mass>();
		springs = new Vector<Spring>();
		forces = new Vector<Vector2D>();
	}
	
	public void addMass(Mass m) {
		masses.add(m);
		forces.add( new Vector2D() );
	}
	
	public void addSpring(Spring s) {
		springs.add(s);
	}
	
	public void deleteMass() {
		
	}
	
	public void deleteSpring() {
		
	}
	
	public int getNumberOfMasses() {
		return masses.size();
	}
	
	public int getNumberOfStrings() {
		return springs.size();
	}
	
	public Mass getMass(int index) {
		return masses.elementAt(index);
	}
	
	public Spring getSpring(int index) {
		return springs.elementAt(index);
	}
	
	/*
	 * su anki haliyle 1 boyutlu bir kutle dizisi icin uygun
	 * oysa bir mass'e iki'den fazla spring baglansa 2D grid de yapilabilir. 
	 */
	public void simulate(double dt) {
		int nMasses = masses.size();
		int nSprings = springs.size();
		double forceX = 0.0;
		double forceY = 0.0;
		
		/*
		 * first, calculate forces
		 */
		for(int i=0; i<nMasses; i++) {
			Mass m = masses.elementAt(i);
			forceX = forceY = 0.0;
			
			for(int j = 0; j<nSprings; j++) {
				Spring s = springs.elementAt(j);
				forceX += s.getForce(m).x;
				forceY += s.getForce(m).y;
			}
			forces.elementAt(i).set(forceX, forceY);
		}
		/*
		 * then, apply the forces to masses according to their constraints
		 */
		for(int i=0; i<nMasses; i++) {
			Mass m = masses.elementAt(i);
			forceX = forces.elementAt(i).x;
			forceY = forces.elementAt(i).y;
				
			switch( m.getConstraint() ) {
			case Mass.NO_CONSTRAINT:			
				m.applyForce( new Vector2D(forceX, forceY), dt ) ;
				break;
			case Mass.X_ONLY:
				m.applyForce( new Vector2D(forceX, 0.0), dt ) ;
				break;
			case Mass.Y_ONLY:
				m.applyForce( new Vector2D(0.0, forceY), dt ) ;
				break;
			case Mass.NO_FREEDOM:
				break;
			}
		}
	}
}

